package com.yt.order.common.utils;

import com.google.gson.Gson;
import com.google.gson.annotations.SerializedName;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

import java.io.IOException;
import java.math.BigDecimal;
import java.net.URLEncoder;

/**
 * 腾讯地图地址转经纬度工具类（经纬度使用BigDecimal高精度存储）
 */
public class TencentMapGeocoder {

    // 腾讯地图地理编码API地址
    private static final String GEOCODER_API_URL = "https://apis.map.qq.com/ws/geocoder/v1/";
    // 替换为你的腾讯地图开发者Key（必填）
    private static final String TENCENT_MAP_KEY = "H2YBZ-CXGET-CE6XB-LVIGD-4TXDS-7BF2B";

    // HTTP客户端（单例复用）
    private static final OkHttpClient HTTP_CLIENT = new OkHttpClient();
    // JSON解析器（单例复用）
    private static final Gson GSON = new Gson();

    /**
     * 地理编码API响应实体类（内部类，封装返回结果）
     */
    public static class GeocoderResponse {
        private int status; // 状态码：0=成功，其他为错误
        private String message; // 错误信息（status非0时有效）
        private Result result; // 成功时的结果数据

        public int getStatus() {
            return status;
        }

        public String getMessage() {
            return message;
        }

        public Result getResult() {
            return result;
        }

        /**
         * 响应结果详情（内部类）
         */
        public static class Result {
            @SerializedName("location") // 确保JSON字段"location"正确映射
            private Location location; // 经纬度信息（高精度）

            public Location getLocation() {
                return location;
            }
        }

        /**
         * 经纬度实体（使用BigDecimal存储，高精度）
         */
        public static class Location {
            @SerializedName("lat") // JSON字段"lat"映射到纬度
            private BigDecimal lat; // 纬度（高精度）
            @SerializedName("lng") // JSON字段"lng"映射到经度
            private BigDecimal lng; // 经度（高精度）

            public BigDecimal getLat() {
                return lat;
            }

            public BigDecimal getLng() {
                return lng;
            }
        }
    }

    /**
     * 将地址转换为经纬度（返回BigDecimal高精度类型）
     * @param address 待转换的地址（如"上海市浦东新区世纪大道"）
     * @param region 可选：城市名（缩小解析范围，提高精度，如"上海"）
     * @return 经纬度对象（lat=纬度, lng=经度，BigDecimal类型），失败返回null
     */
    public static GeocoderResponse.Location addressToLatLng(String address, String region) {
        if (address == null || address.trim().isEmpty()) {
            System.err.println("地址不能为空");
            return null;
        }

        try {
            // 1. 编码地址（处理中文和特殊字符）
            String encodedAddress = URLEncoder.encode(address.trim(), "UTF-8");
            // 2. 构建请求URL
            StringBuilder urlBuilder = new StringBuilder(GEOCODER_API_URL);
            urlBuilder.append("?address=").append(encodedAddress);
            urlBuilder.append("&key=").append(TENCENT_MAP_KEY);
            // 可选参数：添加城市范围
            if (region != null && !region.trim().isEmpty()) {
                urlBuilder.append("&region=").append(URLEncoder.encode(region.trim(), "UTF-8"));
            }

            // 3. 发送HTTP GET请求
            Request request = new Request.Builder().url(urlBuilder.toString()).build();
            try (Response response = HTTP_CLIENT.newCall(request).execute()) {
                if (!response.isSuccessful()) {
                    throw new IOException("HTTP请求失败: " + response.code() + " " + response.message());
                }

                // 4. 解析响应JSON（Gson自动将数字转换为BigDecimal）
                String responseBody = response.body().string();
                GeocoderResponse geocoderResponse = GSON.fromJson(responseBody, GeocoderResponse.class);

                // 5. 校验返回状态
                if (geocoderResponse.getStatus() == 0 && geocoderResponse.getResult() != null
                        && geocoderResponse.getResult().getLocation() != null) {
                    return geocoderResponse.getResult().getLocation();
                } else {
                    System.err.println("地理编码失败：" + geocoderResponse.getMessage() + "（状态码：" + geocoderResponse.getStatus() + "）");
                    return null;
                }
            }
        } catch (Exception e) {
            System.err.println("地址转换异常：" + e.getMessage());
            e.printStackTrace();
            return null;
        }

    }
}
